##################################################################################
### config
##################################################################################
CC                  := gcc
AR                  := ar
CSTD                := c11
BUILT_DIR           = built
TARGET              = app
LIB                 = varch

##################################################################################
### source locations
##################################################################################
WORKSPACE           = source
TESTSPACE           = test
APPLICATION_PATH    = $(WORKSPACE)/00_application
GENDATA_PATH        = $(WORKSPACE)/01_general
VSTD_PATH           = $(WORKSPACE)/02_vstd
CONTAINER_PATH      = $(WORKSPACE)/03_container
ALGORITHM_PATH      = $(WORKSPACE)/04_algorithm
PARSER_PATH         = $(WORKSPACE)/05_parser
PERFORMANCE_PATH    = $(WORKSPACE)/06_performance
MATH_PATH    		= $(WORKSPACE)/07_math

##################################################################################
### sources, libaries and head path
##################################################################################
INCLUDE             += $(APPLICATION_PATH)
INCLUDE             += $(GENDATA_PATH)
INCLUDE             += $(VSTD_PATH)
INCLUDE             += $(CONTAINER_PATH)
INCLUDE             += $(ALGORITHM_PATH)
INCLUDE             += $(PARSER_PATH)
INCLUDE             += $(PERFORMANCE_PATH)
INCLUDE             += $(MATH_PATH)

LIBSRCS             += $(APPLICATION_PATH)/init.c
LIBSRCS             += $(wildcard $(APPLICATION_PATH)/console/*.c)
LIBSRCS             += $(wildcard $(GENDATA_PATH)/*.c)
LIBSRCS             += $(wildcard $(VSTD_PATH)/*.c)
LIBSRCS             += $(wildcard $(CONTAINER_PATH)/*.c)
LIBSRCS             += $(wildcard $(ALGORITHM_PATH)/*.c)
LIBSRCS             += $(wildcard $(PARSER_PATH)/*.c)
LIBSRCS             += $(wildcard $(PERFORMANCE_PATH)/*.c)
LIBSRCS             += $(wildcard $(MATH_PATH)/*.c)

LIBLIST             += m
LIBLIST             += pthread
# LIBLIST             += X11

CFLAG               += -std=$(CSTD)
# CFLAG               += -Wall
# CFLAG               += -Werror

##################################################################################
### test source
##################################################################################

include $(TESTSPACE)/test.mk

TESTSRC             += $(APPLICATION_PATH)/main.c
TESTSRC             += $(patsubst %,$(TESTSPACE)/test_%.c,$(TEST_LIST))

ifeq ($(OS),Windows_NT)
    UNAME := Windows
else
    UNAME := $(shell uname -s)
endif

##################################################################################
### recipes
##################################################################################
INCS                = $(addprefix -I,$(INCLUDE))
LIBS                = $(addprefix -l,$(LIBLIST))
OBJP                = $(BUILT_DIR)/obj
BINP                = $(BUILT_DIR)/bin
LIBO                = $(patsubst %.c, $(OBJP)/%.o, $(LIBSRCS))
TSTO                = $(patsubst %.c, $(OBJP)/%.o, $(TESTSRC))
OBJS                = $(LIBO) $(TSTO)
TARP                = $(BINP)/$(TARGET)
LIBN                = lib$(LIB)
LIBA                = $(BUILT_DIR)/$(LIBN).a
LIBP                ?= /usr

##################################################################################
### make targets
##################################################################################

# link
${TARP}:$(OBJS)
	@ mkdir -p $(dir $@)
	@ $(CC) $(CFLAG) $(OBJS) -o $(TARP) $(LIBS) 

# compile
$(OBJP)/%.o:%.c
	@ mkdir -p $(dir $@)
	@ echo "compiling $(notdir $<)"
	@ $(CC) $(CFLAG) $(INCS) -c $< -o $@

app:${TARP}

$(TEST_LIST): %: $(TESTSPACE)/test_%.c
	@ mkdir -p $(BINP)
	@ $(CC) $(CFLAG) -o $(BINP)/$@ $< -DTEST_TARGET_$@ $(LIBS) -l$(LIB) -lm

# lib
lib:$(LIBO)
	@ $(AR) -crv $(LIBA) $(LIBO)

.PHONY:help
help:
	@echo "Makefile Help"
	@echo "Usage: make [target] [options]"
	@echo ""
	@echo "Available targets:"
	@echo ""
	@echo "  app        - Build the project (default target $(TARP))"
	@echo "             [CC] - Specify the compiler (default is $(CC))"
	@echo "             [AR] - Specify the archiver (default is $(AR))"
	@echo "             [CSTD] - Specify the C std version (c89, c99, c11, c18, default is $(CSTD))"
	@echo ""
	@echo "  lib        - Build the library ($(LIB))"
	@echo ""
	@echo "  [test]     - Build test app, and link to $(LIB) lib"
	@echo "             Test target: $(TEST_LIST)"
	@echo ""
	@echo "  run        - Execute the default application"
	@echo ""
	@echo "  install    - Install the library"
	@echo "             [LIBP] - Specify the lib installation path (default is $(LIBP))"
	@echo "                      example: linux - make install"
	@echo "                               MinGW - make install LIBP=D:/MinGW"
	@echo ""
	@echo "  uninstall  - Uninstall the library"
	@echo "             [LIBP] - Same as install"
	@echo ""
	@echo "  clean      - Remove build artifacts"
	@echo ""
	@echo "  help       - Show this help message"
	@echo ""

	
.PHONY:clean
clean:
	@echo "remove app and objs files ..."
	@ rm $(BUILT_DIR)/$(WORKSPACE) -rf
	@ rm $(BUILT_DIR)/* -rf

.PHONY:run
run:app
	@ echo "executing..."
	./$(BUILT_DIR)/bin/$(TARGET)

.PHONY:install
install:lib
	@ mkdir -p $(LIBP)/include/$(LIB)
	@ find $(INCLUDE) -name "*.h" -exec cp {} $(LIBP)/include/$(LIB) \;
	@ mv -f $(LIBA) $(LIBP)/lib \
		&& ( echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" && \
			 echo "[INFO] varch install success !!!" && \
			 echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx") \
		|| ( echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" && \
			 echo "[ERROR] varch install fail !!!" && \
			 echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" && \
			 rm $(LIBP)/include/$(LIB) -rf )
#	@ ldconfig

.PHONY:uninstall
uninstall: 
	@ rm $(BUILT_DIR)/$(LIB) -rf
	@ rm $(LIBP)/lib/$(LIBN).a
	@ rm $(LIBP)/include/$(LIB) -rf
#	@ ldconfig
